﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;
#if WINDOWS
using System.Runtime.Serialization.Formatters.Binary;
#endif
using System.IO;

namespace CorporationWars
{
#if WINDOWS
    [Serializable]
#endif
    public class SerializableBase<T>
#if WINDOWS
        : ISerializable
#endif
    {
        /// <summary>
        /// ctor
        /// </summary>
        public SerializableBase() { }

#if WINDOWS
        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="info">Data to be serialized</param>
        /// <param name="context">Streaming context</param>  
        public SerializableBase(SerializationInfo info, StreamingContext ctxt)
            : this()
        {
            PropertyInfo[] properties = typeof(T).GetProperties();

            int propertyCount = properties.Length;

            for (int p = 0; p < propertyCount; p++)
                properties[p].SetValue(this, info.GetValue(properties[p].Name, properties[p].PropertyType), null);
        }
#endif
        /// <summary>
        /// Method to serialize the object
        /// </summary>
        /// <returns></returns>
        public static byte[] Serialize<T>(T objectInsatnce) where T : class
        {
#if WINDOWS
            BinaryFormatter formatter = new BinaryFormatter();
#else
            DataContractSerializer formatter = new DataContractSerializer(typeof(T));
#endif

            MemoryStream memStream = new MemoryStream();
#if WINDOWS
            formatter.Serialize(memStream, objectInsatnce);
#else
            formatter.WriteObject(memStream, objectInsatnce);
#endif
            byte[] buffer = memStream.ToArray();
            memStream.Close();

            

            return buffer;

        }

        public static byte[] Serialize(T objectInsatnce)
        {
#if WINDOWS
            BinaryFormatter formatter = new BinaryFormatter();
#else
            DataContractSerializer formatter = new DataContractSerializer(typeof(T));
#endif

            byte[] buffer=null;
            using (MemoryStream memStream = new MemoryStream())
            {
#if WINDOWS
                formatter.Serialize(memStream, objectInsatnce);
#else
                formatter.WriteObject(memStream, objectInsatnce);
#endif
                buffer = memStream.ToArray();
                memStream.Close();
            }

            return buffer;

        }    

        /// <summary>
        /// Method to deserialize the object from a byte array
        /// </summary>
        /// <param name="buffer">byte array holding the serialized object</param>
        /// <returns>Deserialized instance of the object</returns>
        public static T Deserialize<T>(byte[] buffer) where T: class
        {
#if WINDOWS
            BinaryFormatter formatter = new BinaryFormatter();
#else
            DataContractSerializer fomratter = new DataContractSerializer(typeof(T));
#endif
            T retVal = default(T);
            using (MemoryStream memStream = new MemoryStream(buffer))
            {

#if WINDOWS
                retVal = (T)formatter.Deserialize(memStream);
#else
                retVal = (T)fomratter.ReadObject(memStream);

#endif
                memStream.Close();
            }

            return retVal;
        }

        public static T Deserialize(byte[] buffer) 
        {
#if WINDOWS
            BinaryFormatter formatter = new BinaryFormatter();
#else
            DataContractSerializer fomratter = new DataContractSerializer(typeof(T));
#endif
            T retVal = default(T);
            using (MemoryStream memStream = new MemoryStream(buffer))
            {

#if WINDOWS
                retVal = (T)formatter.Deserialize(memStream);
#else
                retVal = (T)fomratter.ReadObject(memStream);

#endif
                memStream.Close();
            }
            return retVal;
        }
        public static void Deserialize(byte[] buffer, ref T obj)
        {
#if WINDOWS
            BinaryFormatter formatter = new BinaryFormatter();
#else
            DataContractSerializer fomratter = new DataContractSerializer(typeof(T));
#endif
            using (MemoryStream memStream = new MemoryStream(buffer))
            {

#if WINDOWS
                obj = (T)formatter.Deserialize(memStream);
#else
                obj = (T)fomratter.ReadObject(memStream);

#endif
                memStream.Close();
            }            
        }
#if WINDOWS
        /// <summary>
        /// Needed to do binary serailization of this object
        /// </summary>
        /// <param name="info">Data to be serialized</param>
        /// <param name="context">Streaming context</param>  
        public virtual void GetObjectData<T>(SerializationInfo info, StreamingContext context) where T : class
        {
            PropertyInfo[] properties = typeof(T).GetProperties();

            int propertyCount = properties.Length;

            for (int p = 0; p < propertyCount; p++)
                info.AddValue(properties[p].Name, properties[p].GetValue(this, null));
        }

        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            PropertyInfo[] properties = this.GetType().GetProperties();

            int propertyCount = properties.Length;

            for (int p = 0; p < propertyCount; p++)
                info.AddValue(properties[p].Name, properties[p].GetValue(this, null));
        }
#endif 
    }
}
